package io;

import java.io.*;
/**
 * 使用缓冲流完成文件复制操作
 *
 * java将流分为:节点流和处理流
 * 节点流:也称为低级流,特点:是实际连接程序和另一端的管道,负责真实读写文件数据的流.读写一定是建立在
 *       节点流基础上进行的.
 * 处理流:也称为高级流,特点:不能独立存在,必须连接在其它流上才能工作.作用是当数据经过当前流时可以对其
 *       进行加工处理,简化我们在IO中对数据的相同操作.
 *
 * 实际开发中,我们可以串联一组高级流到某个低级流上,使得数据读写的过程中可以以"流水线"式的加工完成工作
 * 这种操作也称为:"流的连接"
 *
 *  缓冲字节流
 *  java.io.BufferedInputStream和BufferedOutputStream
 *  缓冲字节流继承自InputStream和OutputStream
 *
 *  缓冲流是一对高级流,在流连接中使用目的是保证读写效率.
 */
public class CopDemo3 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("./one.jpg");
        BufferedInputStream bis=new BufferedInputStream(fis);//缓冲输入流
        /*
            高级流的构造器通常要求传入一个流,用于将当前高级流连接其上.

            缓冲流默认创建时内部数组长度为8192(8kb)
            可以通过重载的构造器调整:
            BufferedInputStream(InputStream in,int bufferSize)
         */
        FileOutputStream fos=new FileOutputStream("./two.jpg");
        BufferedOutputStream bos=new BufferedOutputStream(fos);//缓冲输出流

        int d;
        long start=System.currentTimeMillis();
       /*
            当我们调用缓冲流的read或write方法读取单字节时,缓冲流实际上是转换成块读写形式进行的.
            以read方法为例
            BufferedInputStream内部默认有一个8kb的byte数组,当第一次调用read()读取一个字节时
            缓冲流实际上通过其连接的流一次性读取8kb数据并存入其数组中,然后仅将第一个字节通过read
            方法返回.当第二次调用read()方法时,缓冲流就会直接将数组第二个字节返回(此时不会再去读取
            硬盘).读第三个,第四个...都不会读取硬盘.直到8kb数据全部读取完毕才会再次读取8kb回来.
         */
        while ((d=bis.read())!=-1){//读取
            bos.write(d);//写出
        }
        long end=System.currentTimeMillis();
        System.out.println("复制完毕,用时"+(end-start)+"ms");

        bos.close();
        bis.close();
    }
}
